﻿using System;
using System.ServiceModel;

namespace LayeredArchitectureSample.Infrastructure.Services
{
    public interface IServiceOperationInvoker<TService> : IDisposable
        where TService : class
    {
        /// <summary>
        /// Invokes an operation on a remote service.
        /// Note: rethrows all exceptions encountered.
        /// Note: quite limited at the moment, execute no more than one service operation per call.
        /// </summary>
        /// <typeparam name="TResult">Return type of service operation being executed.</typeparam>
        /// <param name="serviceOperationToInvoke">A delegate that describes which service operation must be invoked.</param>
        /// <returns>Value returned as the result of invocatio of service' operation.</returns>
        /// <exception cref="TimeoutException"></exception>
        /// <exception cref="CommunicationException"></exception>
        TResult Invoke<TResult>(Func<TService, TResult> serviceOperationToInvoke);

        /// <summary>
        /// Invokes an operation (that does not have a result) on a remote service.
        /// Note: rethrows all exceptions encountered.
        /// Note: quite limited at the moment, execute no more than one service operation per call.
        /// </summary>
        /// <param name="serviceOperationToInvoke">A delegate that describes which service operation must be invoked.</param>
        /// <exception cref="TimeoutException"></exception>
        /// <exception cref="CommunicationException"></exception>
        void Invoke(Action<TService> serviceOperationToInvoke);
    }
}